home *** CD-ROM | disk | FTP | other *** search
- /*
- TMS9900/99105 Cross-Assembler v. 1.0
-
- January, 1985
-
- Original 6800 version Copyright (c) 1980 William C. Colley, III.
- Modified for the TMS9900/99105 Series by Alexander Cameron.
-
- File: a99symb.c
-
- Routines to manipulate the symbol table.
- */
-
- /* Get Globals: */
-
- #include "a99.gbl"
-
- /*
- This function adds a new entry to the symbol table. The function
- returns values of either 0 or -1. If the value is 0, the symbol is
- already in the table and the global variable sympoint points to the
- existing entry. If the value is -1, the symbol has just been entered
- into the table and sympoint points to the new entry. If the symbol
- table is full, the function triggers an abort of the assembly.
- */
-
- addsym(symbol)
- char *symbol;
- {
- int t;
- if ((t = slookup(symbol)) > 0)
- {
- wipeout("\nSymbol Table Overflow.\n");
- }
- if (t != 0) movmem(symbol, sympoint, SYMLEN);
- return(t);
- }
-
- /*
- This function checks the symbol table for a given symbol. The function returns
- one of three values as follows:
-
- 1 = symbol not found and symbol table full.
- 0 = symbol found. sympoint points to the matching entry.
- -1 = symbol not found. sympoint points to where the symbol
- should have been.
-
- Jan 85 - Added code to cater for quadratic probing when handling
- collisions. (See Wirth's Algorithms + Data Structures = Programs
- pp 268)
- */
- slookup(symbol)
- char *symbol;
- {
- int h,d;
- d=1;
- h=hash(symbol);
- sympoint = &symtbl[h];
- while((sympoint -> symname[0] & 0x7f) != '\0')
- {
- if (symcmp(symbol,sympoint->symname) == 0) return(0);
- h += d;
- d += 2;
- sympoint = &symtbl[h];
- if (h >= SYMBOLS) h -= SYMBOLS;
- if (d == SYMBOLS) return(1);
- }
- return(-1);
- }
-
- /*
- This function returns a hash value for a given symbol. The hash value
- is calculated by folding the symbol name up into 16 bits (2 bytes, thus
- the symbol length must be even) mod the number of symbols.
-
- The earlier versions of the cross-assembler assigned j as an int
- consequently if j took on a value greater than 32367 the entry pointer
- overflowed and the assembler wound up stuffing symbols into the middle
- of the programme. Assigning j to unsigned solved this bug.
- */
-
- hash(symbol)
- char *symbol;
- {
- char i;
- unsigned j;
- for (i = j = 0; i < (SYMLEN / 2); i++)
- {
- j += (*symbol++ << 8) + *symbol++;
- }
- return(j % SYMBOLS);
- }
-
- /*
- Function to sort the symbol table. The function
- returns the number of entries in the table.
-
- Set flag if you just want a count
- */
- sortsym(flag)
- char flag;
- {
- int n, symcmp();
- struct symbtbl *tptr;
- n = 0;
- for (tptr = sympoint = symtbl; tptr < symend; tptr++)
- {
- if ((tptr -> symname[0] & 0x7f) != '\0')
- {
-
- if(!flag )
- {
- movmem(tptr->symname,sympoint->symname,(SYMLEN+2));
- sympoint++;
- }
- n++;
- }
- }
- if(flag) return n;
- qsort(&symtbl,n,(SYMLEN+2),&symcmp);
- return n;
- }
-
- /*
- This function compares two symbols. It returns zero if the
- symbols are the same, not zero if they are different.
- */
-
- symcmp(sym1,sym2)
- char *sym1, *sym2;
- {
- char i;
- int t;
- for (i = 0; i < SYMLEN; i++)
- {
- if ((t = (*sym1++ & 0x7f) - (*sym2++ & 0x7f)) != 0) break;
- }
- return(t);
- }
-
- /*
- Function to abort an assembly. The parameter reason holds a string that
- will be printed to explain why the assembly bombed. Note that I can't just
- call exit since this will not restore the currently logged disk drive, and
- software that changes the currently logged disk drive annoys me greatly.
- */
-
- wipeout(reason)
- char *reason;
- {
- puts(reason);
- exit();
- }
-